package com.haibara.codesandbox.config;

import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.api.command.InspectImageResponse;
import com.github.dockerjava.api.exception.NotFoundException;
import com.github.dockerjava.core.DefaultDockerClientConfig;
import com.github.dockerjava.core.DockerClientImpl;
import com.github.dockerjava.httpclient5.ApacheDockerHttpClient;
import com.github.dockerjava.transport.DockerHttpClient;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

import java.time.Duration;
import java.util.concurrent.TimeUnit;

/**
 * Docker客户端初始类
 *
 * @Author: mengyu
 * @Date: 2025/1/2
 */
@Component
@Slf4j
public class DockerClientInit {
    @Resource
    private DockerConfigProperties dockerConfigProperties;

    @Bean
    public DockerClient dockerClient() {
        // Docker 配置
        DefaultDockerClientConfig config = DefaultDockerClientConfig.createDefaultConfigBuilder()
                .withDockerHost(dockerConfigProperties.getHost())
                .withApiVersion(dockerConfigProperties.getApiVersion())
                .withRegistryUrl(dockerConfigProperties.getRegistryUrl())
                .withDockerTlsVerify(false)
                .build();

        // 创建DockerHttpClient
        DockerHttpClient httpClient = new ApacheDockerHttpClient
                .Builder()
                .dockerHost(config.getDockerHost())
                .maxConnections(100)
                .connectionTimeout(Duration.ofSeconds(300))
                .responseTimeout(Duration.ofSeconds(300))
                .build();

        // 连接Docker
        DockerClient dockerClient = DockerClientImpl.getInstance(config, httpClient);
        log.info("docker 初始化成功");
        // 拉取镜像
        checkAndPullAlpine(dockerClient);
//        dockerClient.pullImageCmd("busybox");
        return dockerClient;
    }


    private void checkAndPullAlpine(DockerClient dockerClient) {
        final String ALPINE_IMAGE = "alpine:3.12.0";

        try {
            // 尝试获取镜像信息（检查是否存在）
            InspectImageResponse inspectResponse = dockerClient.inspectImageCmd(ALPINE_IMAGE).exec();
            assert inspectResponse.getRepoTags() != null;
            assert inspectResponse.getId() != null;
            log.info("alpine镜像已存在: {} (ID: {})",
                    inspectResponse.getRepoTags().get(0),
                    inspectResponse.getId().substring(0, 12));
        } catch (NotFoundException e) {
            log.warn("未找到alpine镜像，开始拉取...");

            try {
                // 拉取镜像并等待完成
                dockerClient.pullImageCmd(ALPINE_IMAGE)
                        .start()
                        .awaitCompletion(180, TimeUnit.SECONDS); // 设置3分钟超时

                log.info("alpine镜像拉取成功");
            } catch (InterruptedException ex) {
                Thread.currentThread().interrupt();
                log.error("alpine镜像拉取被中断", ex);
            } catch (Exception ex) {
                log.error("alpine镜像拉取失败", ex);
                // 根据您的需求决定是否抛出异常
                // throw new RuntimeException("alpine镜像安装失败", ex);
            }
        } catch (Exception e) {
            log.error("检查alpine镜像时发生错误", e);
        }
    }
}
